import { successFindAll, successFindOne, successPagination } from 'src/common/responses';
import { QueryPaginationType } from 'src/typings';
import { Model, FilterQuery, QueryOptions } from 'mongoose';
import { omitBy, isNil, isString } from 'lodash';
import { HttpErrorException } from 'src/common/exceptions';
import { isDeletedFindFileter } from '../base';

/**
 * 将查询参数变为模糊查询
 */
export const toFuzzyParams = (params) => {
  const newParams = {};
  Object.keys(params).forEach((key) => {
    const value = params[key]
    if (isString(value)) {
      newParams[key] = new RegExp(`${params[key]}`);
    } else {
      newParams[key] = value
    }
  });
  return newParams;
};

const getFilterQuery = <T>(queryParams: FilterQuery<T>) => {
  return {
    ...isDeletedFindFileter,
    ...omitBy(queryParams, isNil)
  }
}

/**
 * 通用分页请求查询
 * @param model DBModel
 * @param queryDto 查询参数
 * @returns 查询结果
 */
export const queryPagination = async <M, D>(
  model: Model<M>,
  queryParams: FilterQuery<D>,
  pagination: QueryPaginationType,
  options?: QueryOptions,
  projection?: any
) => {
  const { pageSize, current } = pagination;
  try {
    const data = await model
      .find(
        getFilterQuery(queryParams),
        {
          ...projection,
          isDeleted: 0,
        },
        {
          limit: pageSize,
          skip: pageSize * (current - 1),
          sort: '-createdTime',
          ...options
        }
      ).exec();

    return successPagination({
      data,
      pagination: {
        total: await model.count().exec(),
        pageSize,
        current,
      },
    });
  } catch (error: any) {
    throw new HttpErrorException(new Error(error).message);
  }
};

/**
 *
 * @param model DBModel
 * @param _id 数据_id
 * @returns 查询结果
 */
export const getOneById = async <M>(
  model: Model<M>,
  _id: string,
) => {
  try {
    const data = await model.findById(_id, {

    }).exec();
    return successFindOne({
      data,
      message: '查找成功',
    });
  } catch (error: any) {
    throw new HttpErrorException(new Error(error).message);
  }
};

/**
 * 根据条件获取所有数据
 * @param model DBModel
 * @param queryDto 查询参数
 * @params options {
 *    sort: 排序
 * }
 * @returns 查询结果
 */
export const getAll = async<M, D>(
  model: Model<M>,
  queryParams: FilterQuery<D>,
  options = {
    sort: '-createdTime'
  }
) => {
  try {
    const {
      sort
    } = options
    const data = await model
      .find(getFilterQuery(queryParams))
      .sort(sort)
      .exec();

    return successFindAll({
      data,
      total: await model.count().exec(),
    });
  } catch (error: any) {
    throw new HttpErrorException(new Error(error).message);
  }
};
